package com.logic.landseaserver.models.payment.service;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.logic.common.domain.Code;
import com.logic.common.security.SecurityUtils;
import com.logic.landseaserver.common.enums.BTypeEnum;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.exception.ResultCodes.PaymentResultCode;
import com.logic.landseaserver.common.util.LandSeaUtil;
import com.logic.landseaserver.common.util.StringTools;
import com.logic.landseaserver.domain.Account;
import com.logic.landseaserver.domain.BillPayment;
import com.logic.landseaserver.domain.Contract;
import com.logic.landseaserver.domain.RealBill;
import com.logic.landseaserver.domain.RoomPwdSmsInfo;
import com.logic.landseaserver.domain.ShiJiProjectConfig;
import com.logic.landseaserver.models.payment.PaymentConstant.BillTypeCode;
import com.logic.landseaserver.models.payment.bean.ShiJiPaymentResponse;
import com.logic.landseaserver.models.payment.config.ShijiPaymentConfig;
import com.logic.landseaserver.models.prepayment.service.PrepaymentService;
import com.logic.landseaserver.persistence.read.AccountReadMapper;
import com.logic.landseaserver.persistence.read.BillPaymentReadMapper;
import com.logic.landseaserver.persistence.read.BillReadMapper;
import com.logic.landseaserver.persistence.read.ContractReadMapper;
import com.logic.landseaserver.persistence.read.DepositReadMapper;
import com.logic.landseaserver.persistence.read.ProjectReadMapper;
import com.logic.landseaserver.persistence.read.RealBillReadMapper;
import com.logic.landseaserver.persistence.read.ShiJiProjectConfigReadMapper;
import com.logic.landseaserver.persistence.write.ShiJiProjectConfigWriteMapper;
import com.logic.landseaserver.ws.dto.BillDTO;
import com.logic.landseaserver.ws.dto.DepositDTO;
import com.logic.landseaserver.ws.dto.ProjectDetailForFrontDTO;
import com.logic.system.persistence.read.CodeReadMapper;

/**
 * 
 *
 * 项目名称：system-server</br>
 * 类名称：ShiJiPaymentService</br>
 * 类描述：银石支付服务入口</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年7月17日 下午4:29:22</br>
 * 
 * @version 1.0
 *
 */
@Service
public class ShiJiPaymentService
{
    protected static final Logger LOGGER = LoggerFactory.getLogger(ShiJiPaymentService.class);
    
    @Autowired
    private BillPaymentReadMapper billPaymentReadMapper;
    
    @Autowired
    private BillReadMapper billReadMapper;
    
    @Autowired
    private ContractReadMapper contractReadMapper;
    
    @Autowired
    private RealBillReadMapper realBillReadMapper;
    
    @Autowired
    private CodeReadMapper codeReadMapper;
    
    @Autowired
    private ProjectReadMapper projectReadMapper;
    
    @Autowired
    private ShiJiProjectConfigReadMapper projectConfigReadMapper;
    
    @Autowired
    private ShiJiProjectConfigWriteMapper projectConfigWriteMapper;
    
    @Autowired
    private ShijiPaymentConfig shijiPaymentConfig;
    
    @Autowired
    private DepositReadMapper depositReadMapper;
    
    @Autowired
    private PrepaymentService prepaymentService;
    
    @Autowired
    private AccountReadMapper accountReadMapper;
    
    /**
     * 
     * [简要描述]：查询待支付的记录</br>
     * [详细描述]：银石智能POS扫码读取</br>
     * [作者]：Aaron(2017-07-19)</br>
     *
     * @param paymentId
     * @throws LandseaException
     *
     */
    public Map<String, Object> getPaymentRecord(Integer paymentId)
        throws LandseaException
    {
        Map<String, Object> resultRecord = new HashMap<String, Object>();
        try
        {
            // 查询支付记录
            BillPayment billPayment = billPaymentReadMapper.selectByPrimaryKey(paymentId);
            if (null == billPayment || billPayment.getDeleted())
            {
                throw LandseaException.createException(PaymentResultCode.E00140008);
            }
            
            Integer billId = billPayment.getBillId();
            Integer contractId = null;
            String billMessage = StringUtils.EMPTY;
            String billTypeMsg = StringUtils.EMPTY;
            
            // 根据账单的类型提示不同的账单描述信息
            String billType = billPayment.getBillType();
            
            if (BTypeEnum._BT4.getCode().equals(billType))
            {
                // 预定
                DepositDTO deposit = depositReadMapper.getDepositDetail(billId);
                
                billTypeMsg += "您正在支付朗诗寓";
                
                if (null == deposit)
                {
                    // 账单不存在
                    LOGGER.error("getPaymentRecord|bill dose not exists in deposit.depositId=" + billId);
                    billTypeMsg = "预订款" + billPayment.getMoney() + "元";
                }
                else
                {
                	ProjectDetailForFrontDTO project = projectReadMapper.selectProjectBaseInfo(deposit.getPrjId());
                	if (null != project)
                	{
                		// 项目名称
                		billTypeMsg += project.getPrjName();
                	}
                	
                	billTypeMsg += deposit.getRoomNo() + "的预订款" + billPayment.getMoney() + "元";
                }
            }
            else if (BTypeEnum._BT1.getCode().equals(billType))
            {
                // 首期
                // 查询ls_bill表
                BillDTO lsBillRecord = billReadMapper.selectByPrimaryKey(billId);
                if (null == lsBillRecord)
                {
                    LOGGER.error("getPaymentRecord|bill dose not exists. billId=" + billId);
                    billTypeMsg = "首期款";
                }
                else
                {
                    contractId = lsBillRecord.getContractId();
                    billTypeMsg = "的首期款";
                }
            }
            else if (BTypeEnum._BT2.getCode().equals(billType))
            {
                // 月账单
                // 查询ls_bill表
                BillDTO lsBillRecord = billReadMapper.selectByPrimaryKey(billId);
                if (null == lsBillRecord)
                {
                    LOGGER.error("getPaymentRecord|bill dose not exists. billId=" + billId);
                    billTypeMsg = "月账单费用";
                }
                else
                {
                    contractId = lsBillRecord.getContractId();
                    billTypeMsg = "的" + lsBillRecord.getBillMonth() + "月账单费用";
                }
            }
            else if (BTypeEnum._BT3.getCode().equals(billType))
            {
                // 实时账单
                RealBill realBill = realBillReadMapper.selectByPrimaryKey(billId);
                if (null == realBill)
                {
                    // 账单不存在
                    LOGGER.error("getPaymentRecord|bill dose not exists. billId=" + billId);
                    billTypeMsg = "";
                }
                else
                {
                    contractId = realBill.getContractId();
                    String expendseType = realBill.getExpenseType();
                    Code code = codeReadMapper.selectByPrimaryKey(expendseType);
                    if (null != code)
                    {
                        billTypeMsg = "的" + code.getCodeDescZh() + billPayment.getMoney() + "元";
                    }
                    else
                    {
                        billTypeMsg = "的账单" + billPayment.getMoney() + "元";
                    }
                }
            }
            // 如果是充值
            else if (BillTypeCode.RECHARGE.equals(billType))
            {
                // 检查账户是否存在
                Account account = accountReadMapper.selectByAccountBalanceId(billPayment.getBillId());
                if (null == account || account.getDeleted())
                {
                    throw LandseaException.createException(PaymentResultCode.E00140010);
                }
                
                billTypeMsg = "的账户充值" + billPayment.getMoney() + "元";
                Contract contract = prepaymentService.getEffecitveForAdmin(account.getUserId(), account.getRoomId());
                contractId = contract.getId();
            }
            
            if (null != contractId)
            {
                // 查询合同
                RoomPwdSmsInfo roomPwdSmsInfo = contractReadMapper.getMsgInfoByContractId(contractId);
                if (null == roomPwdSmsInfo)
                {
                    LOGGER.error("getPaymentRecord|contract dose not exists.contractId=" + contractId);
                    billMessage = "您正在支付朗诗寓";
                }
                else
                {
                    billMessage = "您正在支付朗诗寓" + roomPwdSmsInfo.getProjectName() + roomPwdSmsInfo.getHouseNum();
                }
            }
            
            // 您正在支付朗诗寓
            billMessage += billTypeMsg;
            
            // 防止为空，为空时POS机会报错
            if (StringUtils.isEmpty(billMessage))
            {
            	billMessage = " ";
            }
            
            
            // 只返回这些字段
            resultRecord.put("paymentId", paymentId);
            resultRecord.put("status", billPayment.getStatus());
            resultRecord.put("money", LandSeaUtil.get2Double(billPayment.getMoney()));
            resultRecord.put("billMessage", billMessage);
            
            // 赋值回调地址
            resultRecord.put("callbackUrl", shijiPaymentConfig.getPosCallbackUrl());
            
            return resultRecord;
        }
        catch (Exception e)
        {
            LOGGER.error("getPaymentRecord error.", e);
            throw LandseaException.createException(PaymentResultCode.E00150008, e);
        }
    }
    
    /**
     * 
     * [简要描述]：保存银石项目配置</br>
     * [详细描述]：存在就更新，不存在就新增</br>
     * [作者]：Aaron(2017-07-21)</br>
     *
     * @param shiJiProjectConfig
     * @throws LandseaException
     *
     */
    public void saveShiJiProjectConfig(ShiJiProjectConfig shiJiProjectConfig)
        throws LandseaException
    {
        try
        {
            if (null == shiJiProjectConfig)
            {
                return;
            }
            
            // 参数检查
            if (null == shiJiProjectConfig.getProjectId())
            {
                throw LandseaException.createException(PaymentResultCode.E00140009);
            }
            
            // 查询项目是否存在
            // 检查合法性
            ProjectDetailForFrontDTO project =
                projectReadMapper.selectProjectBaseInfo(shiJiProjectConfig.getProjectId());
            
            if (null == project)
            {
                throw LandseaException.createException(PaymentResultCode.E00150012);
            }
            
            // 先查询数据库是否存在
            ShiJiProjectConfig shiJiProjectConfigDb =
                projectConfigReadMapper.selectByPrimaryKey(shiJiProjectConfig.getProjectId());
            
            // 更新公共字段
            shiJiProjectConfig.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
            
            if (null == shiJiProjectConfigDb)
            {
                projectConfigWriteMapper.insertSelective(shiJiProjectConfig);
            }
            else
            {
                projectConfigWriteMapper.updateByPrimaryKeySelective(shiJiProjectConfig);
            }
        }
        catch (LandseaException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            LOGGER.error("saveProjectConfig|save shiji project config failed," + shiJiProjectConfig.toString(), e);
            throw LandseaException.createException(PaymentResultCode.E00150022, e);
        }
    }
    
    /**
     * 
     * [描述]：查询银石项目配置</br>
     *
     * @param shiJiProjectConfig 配置项对象
     * @throws LandseaException
     *
     */
    public ShiJiProjectConfig getShiJiProjectConfig(Integer projectId)
        throws LandseaException
    {
        try
        {
            // 先查询数据库是否存在
            ShiJiProjectConfig shiJiProjectConfig = projectConfigReadMapper.selectByPrimaryKey(projectId);
            return shiJiProjectConfig;
        }
        catch (Exception e)
        {
            LOGGER.error("getShiJiProjectConfig|query failed, projectId=" + projectId, e);
            throw LandseaException.createException(PaymentResultCode.E00150023, e);
        }
    }
    
    /**
     * 
     * [简要描述]：根据项目ID或合同ID查询银石项目配置</br>
     * [详细描述]：优先项目ID，若不存在则根据合同ID</br>
     * [作者]：Aaron(2017-07-21)</br>
     *
     * @param projectId
     * @param contractId
     * @return
     * @throws LandseaException
     *
     */
    public ShiJiProjectConfig getShiJiProjectConfig(Integer projectId, Integer contractId) throws LandseaException
    {
        try
        {
            if (null != projectId)
            {
                // 先查询数据库是否存在
                return projectConfigReadMapper.selectByPrimaryKey(projectId);
            }
            
            if (null == contractId)
            {
                return null;
            }
            
            Contract contract = contractReadMapper.selectByPrimaryKey(contractId);
            
            if (null == contract)
            {
                return null;
            }
            
            // 先查询数据库是否存在
            return projectConfigReadMapper.selectByPrimaryKey(contract.getProjectId());
        }
        catch (Exception e)
        {
            LOGGER.error("getShiJiProjectConfig|query failed, projectId=" + projectId + ",contractId=" + contractId, e);
            throw LandseaException.createException(PaymentResultCode.E00150023, e);
        }
    }
    
    /**
     * 
     * [简要描述]：将银石支付结果通知Map转换成内部对象</br>
     * [详细描述]：直接用对象接收容易产生错误</br>
     * [作者]：Aaron(2017-07-24)</br>
     *
     * @param responseMap
     * @return
     *
     */
    public ShiJiPaymentResponse buildResponseFromRespMap(Map<String, Object> responseMap)
    {
        ShiJiPaymentResponse shiJiPaymentResponse = new ShiJiPaymentResponse();
        
        shiJiPaymentResponse.setPlatformTxnNo(StringTools.getString(responseMap.get("PlatformTxnNo")));
        shiJiPaymentResponse.setNotifyType(StringTools.getString(responseMap.get("NotifyType")));
        shiJiPaymentResponse.setPayerID(StringTools.getString(responseMap.get("PayerID")));
        shiJiPaymentResponse.setTxnReqTime(StringTools.getString(responseMap.get("TxnReqTime")));
        shiJiPaymentResponse.setPartnerID(StringTools.getString(responseMap.get("PartnerID")));
        shiJiPaymentResponse.setMerchantID(StringTools.getString(responseMap.get("MerchantID")));
        shiJiPaymentResponse.setChannelID(StringTools.getString(responseMap.get("ChannelID")));
        shiJiPaymentResponse.setChannelDisctAmt(StringTools.getString(responseMap.get("ChannelDisctAmt")));
        shiJiPaymentResponse.setCurrencyCode(StringTools.getString(responseMap.get("CurrencyCode")));
        shiJiPaymentResponse.setChannelTxnNo(StringTools.getString(responseMap.get("ChannelTxnNo")));
        shiJiPaymentResponse.setMerchantName(StringTools.getString(responseMap.get("MerchantName")));
        shiJiPaymentResponse.setTotalAmt(StringTools.getString(responseMap.get("TotalAmt")));
        shiJiPaymentResponse.setOrgTxnNo(StringTools.getString(responseMap.get("OrgTxnNo")));
        shiJiPaymentResponse.setTerminalID(StringTools.getString(responseMap.get("TerminalID")));
        shiJiPaymentResponse.setIncomeAmt(StringTools.getString(responseMap.get("IncomeAmt")));
        shiJiPaymentResponse.setMerchantDisctAmt(StringTools.getString(responseMap.get("MerchantDisctAmt")));
        shiJiPaymentResponse.setPointAmt(StringTools.getString(responseMap.get("PointAmt")));
        shiJiPaymentResponse.setSign(StringTools.getString(responseMap.get("Sign")));
        shiJiPaymentResponse.setInvoiceAmt(StringTools.getString(responseMap.get("nvoiceAmt")));
        shiJiPaymentResponse.setOrgOrderNo(StringTools.getString(responseMap.get("OrgOrderNo")));
        
        shiJiPaymentResponse.setRespCode(StringTools.getString(responseMap.get("RespCode")));
        shiJiPaymentResponse.setRespDesc(StringTools.getString(responseMap.get("RespDesc")));
        
        // 将map保存，后续有用
        shiJiPaymentResponse.setResponseMap(responseMap);
        
        return shiJiPaymentResponse;
    }
}
